<template>
  <div>
    <!-- 表单为form模式时样式 -->
    <template v-if="isForm">
      <div style="justify-content: flex-start;" class="btns-group">
        <el-button
          icon="el-icon-plus"
          type="primary"
          size="default"
          @click="addColumn"
          v-if="!disabled"
        >
          {{ btnContent ? btnContent : `添加${$attrs.label}` }}
        </el-button>
        <excel-upload @update="importColumns" v-if="showExcelImport">
          <el-button
            icon="el-icon-download"
            type="primary"
            size="default"
          >
            excel导入
          </el-button>
        </excel-upload>
      </div>
      <div
        class="anvil-dynamic-row"
        v-for="(formItem, index) in tableData"
        :key="index"
        @mouseenter="handleHover(index)"
        @mouseleave="handleLeave(index)"
      >
        <!-- 自定义每一个表单标题 -->
        <div>
          <span class="itemLabel">{{ $attrs.label }} {{ index + 1 }}</span>
          <el-button
            icon="el-icon-delete"
            type="danger"
            circle
            @click="deleteColumn(index)"
            v-if="!disabled && showBtns[index]"
            style="float: right"
          />
        </div>
        <form-render
          ref="valiFormDynamic"
          :options="dynamicColumns[index]"
          :pageId="pageId"
          :inGrid="true"
          :noSkeleton="true"
          v-model:data="tableData[index]"
        />
      </div>
    </template>
    <template v-else>
      <el-form ref="valiFormDynamic" :model="modelForm" label-width="1" :inline="true">
        <el-table :data="tableData" border>
          <el-table-column :width="isCommon ? 80 : 150" align="center">
            <template #header="{}">
              <div class="btns-group">
                <el-button
                  icon="el-icon-plus"
                  type="primary"
                  circle
                  @click="addColumn"
                  :disabled="disabled"
                />
                <excel-upload @update="importColumns" v-if="showExcelImport">
                  <el-button
                    icon="el-icon-download"
                    type="primary"
                    circle
                    :disabled="disabled"
                  />
                </excel-upload>
              </div>
            </template>
            <template #default="scope">
              <div @mouseenter="handleHover(scope.$index)" @mouseleave="handleLeave(scope.$index)">
                <span v-if="!showBtns[scope.$index]">{{ scope.$index + 1 }}</span>
                <el-button
                  v-if="!isCommon && showBtns[scope.$index]"
                  type="primary"
                  icon="el-icon-edit"
                  circle
                  @click="editColumn(scope.row, scope.$index)"
                  :disabled="disabled"
                />
                <el-button
                  v-if="showBtns[scope.$index]"
                  icon="el-icon-delete"
                  type="danger"
                  circle
                  @click="deleteColumn(scope.$index)"
                  :disabled="disabled"
                />
              </div>
            </template>
          </el-table-column>
          <el-table-column
            v-for="(column, index) in children.column"
            :key="index"
            :label="column && column.label"
            min-width="200"
            align="center"
          >
            <template #default="scope">
              <el-form-item
                :prop="'list.' + scope.$index + `.${column.prop}`"
                :required="getRequired(column, scope.row)"
                label=" "
                style="width: 100%"
              >
                <custom-comp-item
                  v-model="scope.row[column.prop]"
                  :item="column"
                  :params="column.params"
                  :key="column.prop"
                  :formData="formData"
                />
              </el-form-item>
            </template>
          </el-table-column>
        </el-table>
      </el-form>
    </template>

    <drag-dialog v-model="showDialog" append-to-body>
      <form-render ref="main" :options="children" :pageId="pageId" :inGrid="true" :noSkeleton="true" v-model:data="curColumnData" />
      <template #footer>
        <dialog-footer @ok="commitColumnData" @cancel="closeDialog" />
      </template>
    </drag-dialog>
  </div>
</template>

<script>
import FormRender from '../../views/form-render/index.vue';
import customCompItem from '../../views/form-render/customCompItem.vue';
import excelUpload from '../excelUpload/excelUpload.vue';
import dayjs from 'dayjs'
import moment from 'moment';
import { cloneDeep } from 'lodash-es'

export default {
  name: 'AnvilDynamic',
  components: { FormRender, customCompItem,excelUpload },
  props: {
    pageId: {
      type: String,
      default: ''
    },
    disabled: {
      type: Boolean,
      default: false
    },
    modelValue: {
      type: [Object, String],
      default: () => {}
    },
    children: {
      type: Object,
      default: () => {}
    },
    dynamicType: {
      type: String,
      default: ''
    },
    limit: {
      type: Number,
      default: 0
    },
    dynamicModel: {
      type: String,
      default: ''
    },
    btnContent: {
      type: String,
      default: ''
    },
    formData: {
      type: Object,
      default: () => {}
    },
    showExcelImport:{
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      tableData: [],
      showDialog: false,
      curColumnData: {},
      curIndex: 0,
      diaglogType: 'add',
      showBtns: [],
      dynamicColumns: [],
      preData: undefined // 记录前data值
    };
  },
  computed: {
    // columns() {
    //   if (this.children && this.children.column) {
    //     const cols = this.children.column.map((col, index) => {
    //       col.disabled = this.disabled;
    //       return col;
    //     });

    //     // 根据数据长度初始化表单渲染数组
    //     if (!this.dynamicColumns.length) {
    //       this.dynamicColumns = [];
    //       if (this.tableData && this.tableData.length) {
    //         for (let i = 0; i < this.tableData.length; i++) {
    //           this.dynamicColumns.push({
    //             ...this.children,
    //             column: cols,
    //           });
    //         }
    //       }
    //     } else {
    //       // 现在子表单内部的数据相应disabled属性，其他属性变化无法带入子表单的表单结构中
    //       this.dynamicColumns.map((dynCol, index) => {
    //         this.$set(this.dynamicColumns[index], "disabled", this.disabled);
    //       });
    //     }
    //     return cols;
    //   } else {
    //     return [];
    //   }
    // },
    modelForm() {
      return { list: this.tableData };
    },
    // 表单格式
    isForm() {
      return this.dynamicType == 'form';
    },
    // 表单模式
    isCommon() {
      return this.dynamicModel == 'common' || !this.dynamicModel;
    }
  },
  watch: {
    modelValue: {
      handler() {
        if (this.modelValue) {
          if (typeof this.modelValue == 'function') {
            this.tableData = this.modelValue();
          } else {
            this.tableData = this.modelValue;
          }
        } else {
          this.tableData = [];
        }

        // 第一次获取值时初始化渲染
        if (this.preData == undefined && this.value !== undefined) {
          this.initDynamicColumns();
          this.preData = this.value;
        }
      },
      immediate: true,
      deep: true
    },
    tableData: {
      handler(newVal, oldVal) {
        this.$emit('update:modelValue', newVal);
      },
      deep: true
    },
    // 目前外部值变化 影响内部值的只有disabled
    disabled: {
      handler(newVal) {
        this.setDynamicColsDisabled();
      },
      immediate: true
    },
    children: {
      handler(newVal) {},
      deep: true
    },
    limit() {}
  },
  created() {
    this.initDynamicColumns();
  },
  methods: {
    addColumn() {
      // 不超过设定的内容数
      if (this.limit > 0 && this.tableData.length == this.limit) {
        this.msgError('最多只能添加' + this.limit + '项！');
        return;
      }
      // 平铺模式
      if (this.isCommon) {
        if (!this.tableData.length) {
          this.tableData = [{}];
          this.showBtns = [false];
          this.dynamicColumns = [
            {
              ...this.children,
              column: cloneDeep(this.children.column)
            }
          ];
        } else {
          this.tableData.push({});
          this.showBtns.push(false);
          this.dynamicColumns.push({
            ...this.children,
            column: cloneDeep(this.children.column)
          });
        }
      }
      // 弹框模式
      else {
        this.diaglogType = 'add';
        this.curColumnData = {};
        if (this.diaglogType == 'add' && this.$refs.main) {
          this.$refs.main.resetFields();
        }
        this.showDialog = true;
      }
    },
    editColumn(row, index) {
      this.curColumnData = { ...row };
      this.curIndex = index;
      this.diaglogType = 'edit';
      this.showDialog = true;
    },
    commitColumnData() {
      this.$refs.main.validateAvueForm((val) => {
        if (val) {
          const data = { ...this.curColumnData };
          if (this.diaglogType == 'add') {
            if (!this.tableData.length) {
              this.tableData[0] = data;
            } else {
              this.tableData.push(data);
            }
          } else {
            this.tableData[this.curIndex] = data;
          }
          this.closeDialog();
        }
      });
    },
    deleteColumn(index) {
      this.tableData.splice(index, 1);
      this.showBtns.splice(index, 1);
      if (this.dynamicColumns.length) {
        this.dynamicColumns.splice(index, 1);
      }
    },
    handleHover(index) {
      if (!this.disabled) {
        this.showBtns[index] = true;
      }
    },
    handleLeave(index) {
      if (!this.disabled) {
        this.showBtns[index] = false;
      }
    },
    closeDialog() {
      if (this.diaglogType == 'add' && this.$refs.main) {
        this.$refs.main.resetFields();
      }
      this.showDialog = false;
    },
    // 对当前子表单内容进行校验
    validateForm(ruleIds) {
      const lines = [];
      // 表单模式
      // eslint-disable-next-line @typescript-eslint/no-this-alias
      let that = this;
      if (this.isForm) {
        // 因为每次删除后增加子表单，ref都会增加一个最新的在数组末尾，这边直接将所有ref进行校验，最后通过promise.all
        // 只要报错就返回
        if (that.$refs['valiFormDynamic']) {
          console.log('that.$refs["valiFormDynamic"]', that.$refs['valiFormDynamic']);
          const len = that.$refs['valiFormDynamic'].length;
          for (let i = len - 1; i >= 0; i--) {
            console.log('index' + i, that.$refs['valiFormDynamic'][i]);
            lines.push(that.$refs['valiFormDynamic'][i].validateAvueForm());
            if(ruleIds){
              const result = that.$refs['valiFormDynamic'][i].operateValidateRules(ruleIds);
              if(!result){
                lines.push(Promise.reject({
                  [this.$attrs.prop]: [
                    {
                      field: this.$attrs.prop,
                      fieldValue: '',
                      message: `子表单的自定义校验规则校验失败`
                    }
                  ]
                }))
              }
            }
          }
        }
      } else {
        lines.push(that.$refs.valiFormDynamic.validate());
      }
      console.log('lines', lines);
      return lines;
    },
    // 对子表单的渲染数据结构进行初始化
    initDynamicColumns() {
      this.dynamicColumns = [];
      if (this.tableData && this.tableData.length) {
        for (let i = 0; i < this.tableData.length; i++) {
          this.dynamicColumns.push({
            ...this.children
          });
        }
      }
      this.setDynamicColsDisabled();
    },
    // 接收disabled属性并传递到内部
    setDynamicColsDisabled() {
      this.dynamicColumns.map((dynCol, index) => {
        dynCol.column.map((child, idx) => {
          const { disabled } = child;
          // 如果子表单disabled为true，内部所有组件为disabled
          if (this.disabled) {
            this.dynamicColumns[index].column[idx]['disabled'] = this.disabled;
          }
          // 否则按照组件自己的disabled值赋值
          else {
            this.dynamicColumns[index].column[idx]['disabled'] = disabled;
          }
        });
      });
    },
    getRequired(item, data) {
      try {
        return item.requiredFunc && data ? eval(item.requiredFunc)(data) : item.isRequired == 'Y';
      } catch (e) {
        console.log('error!', e);
        return item.isRequired == 'Y';
      }
    },
    importColumns(data){
      // 获取prop和文本标题的映射关系
      const propLabelRefect = {}
      this.children.column.map((col)=>{
        const {prop, label} = col
        propLabelRefect[label] = prop
      })

      const newData = data.map((item)=>{
        const backItem = {}
        for(let key in item){
          // 判断是否存在映射关系，只返回有字段的值
          if(propLabelRefect[key] !== undefined){
            // 处理日期格式数据导入后少43秒问题
            if(item[key] instanceof Date){
              const date = dayjs(item[key]).add(44,'second')
              backItem[propLabelRefect[key]] = moment(date.$d).format('YYYY-MM-DD HH:mm:ss')
            }else{
              backItem[propLabelRefect[key]] = item[key]
            }
          }
        }
        return backItem
      })

      console.log('excel',newData)

      this.tableData.push(...newData)
      this.showBtns.push(...new Array(newData.length).fill(false));
      this.dynamicColumns.push(...new Array(newData.length).fill({
        ...this.children,
        column: cloneDeep(this.children.column)
      }));
    }
  }
};
</script>

<style lang="scss" scoped>
.anvil-dynamic-row {
  border-top: 1px dashed #eee;

  &:first-of-type {
    border-top: 0px;
  }
}

.itemLabel {
  font-size: 14px;
  color: #606266;
  font-weight: 700;
}

.btns-group {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
}
</style>
